#include"test.h"
//定义接口函数

SListNode* BuyNewNode(SListDataType x)
{
	SListNode* NewNode = (SListNode*)malloc(sizeof(SListNode));
	if (NewNode == NULL)   //申请失败的情况
	{
		printf("申请结点失败\n");
		exit(-1);
	}
	NewNode->data = x;
	NewNode->next = NULL;
	return NewNode;
}

//使用二级指针才能真正的根据地址来更改链表的数据
void SListPushBack(SListNode** ppHead, SListDataType x)//尾插，注意，需要动态申请出一个结点，先申请，再插入
{
	SListNode* NewNode = BuyNewNode(x);
	if (*ppHead == NULL)//防止出现空指针的解引用  重复开辟空间代码冗余，所以再增加一个函数接口
	{
		*ppHead = NewNode;
	}
	else 
	{
		//要实现尾插，就要找到尾巴 --> 利用循环和指针指向的next来向下走
		SListNode* tail = *ppHead;
		while (tail->next != NULL)//当出现空指针的解引用，没有结点时程序会崩溃
		{
			tail = tail->next;//不为空就向下走，为空就不走了
		}
		//找到尾巴后要插入结点
		SListNode* NewNode = (SListNode*)malloc(sizeof(SListNode));
		if (NewNode == NULL)   //申请失败的情况
		{
			printf("申请结点失败\n");
			exit(-1);
		}
		NewNode->data = x;
		NewNode->next = NULL;//尾插，尾部要置空
		tail->next = NewNode;
	}
}

void SListPopBack(SListNode** ppHead)
{
	//1.空
	if (*ppHead == NULL)
	{
		return;
	}
	//2.一个
	else if ((*ppHead)->next == NULL)
	{
		free(*ppHead);
		*ppHead = NULL;
	}
	//3.一个以上
	else
	{
		SListNode* prev = NULL;//用来快速找到前驱
		SListNode* tail = *ppHead;
		while (tail->next != NULL)  //注意，尾部指向不为NULL，就继续向后走
		{
			prev = tail;
			tail = tail->next;
		}
		free(tail);//删除尾结点
		prev->next = NULL;
	}
}

void SListPushFront(SListNode** ppHead, SListDataType x)
{
	SListNode* NewNode = BuyNewNode(x);
	//考虑是否有结点
	NewNode->next = *ppHead; //新结点的下一个结点是原来的第一个结点
	*ppHead = NewNode;  //重新指向第一个结点

}

void SListPopFront(SListNode** ppHead)
{
	//1.空表
	if (*ppHead == NULL)
	{
		return;
	}
	//2.一个结点,3.一个以上结点
	else
	{
		SListNode* next = (*ppHead)->next;
		free(*ppHead);
		*ppHead = next;
	}
}

void SListPrint(SListNode* pHead)//打印不需要改变值，所以一级指针就能实现功能
{
	SListNode* cur = pHead;
	while (cur != NULL)
	{
		printf("%d->", cur->data);
		cur = cur->next;//类似于i++
	}
	printf("NULL\n");
}

void SListFindAndModify(SListNode** pphead,int n)//输入要查的位置
{
	int i = 1;
	int m, k;
	SListNode* cur;
	while (i < n)
	{
		if ((*pphead)->next == NULL)
			printf("要查的元素不存在\n");
		else
			*pphead = (*pphead)->next;
		i++;
	}
	printf("查到的数据是%d", (*pphead)->data);//查找到的数据

	cur = *pphead;
	printf("\n请选择要更改的位置：\n");
	scanf_s("%d", &m);
	printf("请输入新数据：\n");
	scanf_s("%d", &k);
	while (i < m)
	{
		if (cur->next == NULL)
			printf("元素不存在\n");
		else
			cur = cur ->next;
		i++;
	}
	cur->data = k;
}

int SListFind(SListNode* phead, int x)
{
	SListNode* cur = phead;
	while (cur)
	{
		if (cur->next == x)
		{
			return cur;
		}
		cur = cur->next;
	}
	return NULL;
}


//只实现代码，不再测试
void SListInsertAfter(SListNode* pos, SListDataType x)
{
	assert(pos);
	SListNode* NewNode = BuyNewNode(x);
	NewNode->next = pos->next;
	pos->next = NewNode;
}

void SListEraseAfter(SListNode* pos)
{
	assert(pos);
	if (pos->next)
	{
		SListNode* next = pos->next;
		SListNode* nextnext = next->next;
		pos->next = nextnext;
		free(next);
	}

}


